﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Campus {
    class BuildStructureAbility : Ability {
        private bool m_ownerIsAtBuildLocation;
        private int m_elapsedTime;
        private BuildingStructure m_buildStructure;
        private bool m_buildIsDone;
        public int ElapsedTime {
            get { return m_elapsedTime; }
        }
        private int m_buildTime;
        public int BuildTime
        {
            get { return m_buildTime; }
        }
        private int m_closeEnoughRange = 75;

        private BuildRequirements.Buildings m_buildingType;

        public BuildStructureAbility(AbilityMenuIcon menuIcon, Unit owner, BuildRequirements.Buildings building)
            : base(menuIcon, owner, null, TargetTypes.PointTarget) {
            m_buildingType = building;
            m_elapsedTime = 0;
            m_ownerIsAtBuildLocation = false;
            m_buildIsDone = false;

            BuildRequirements.Requirements reqs = BuildRequirements.GetRequirements(m_buildingType);
            m_buildTime = reqs.BuildTime;
            MenuDelegate = delegate(string option) {
                if (reqs.CheckRequirements(Owner.PlayerOwner) == true) {
                    Owner.PlayerOwner.IsPlacingStructure = true;
                    Owner.PlayerOwner.PlacingStructure = m_buildingType;
                    Campus.cursor.ClickMethod = delegate(Vector2 gamePoint) {
                        if (Owner.PlayerOwner.IsValidPlace) {
                            Target = gamePoint;
                            Owner.SetCurrentAbility(this);
                            Campus.cursor.ClickMethod = null;
                            Campus.cursor.ActionState = CursorActionState.idle;
                        }
                    };
                } else {
                    Type unitType = BuildRequirements.Requirements.GetType(m_buildingType);
                    string name = unitType.Name;
                    Owner.PlayerOwner.CreateHUDMessage("Construction aborted for " + name + ".  You do not have sufficient resources", 10);
                }
            };
        }
        public BuildStructureAbility(BuildStructureAbility copySource)
            : base(copySource) {
            m_buildingType = copySource.m_buildingType;
            m_elapsedTime = copySource.m_elapsedTime;
            m_ownerIsAtBuildLocation = copySource.m_ownerIsAtBuildLocation;
            m_buildIsDone = copySource.m_buildIsDone;
            m_buildTime = copySource.BuildTime;
            MenuDelegate = delegate(string option) {
                BuildRequirements.Requirements reqs = BuildRequirements.GetRequirements(m_buildingType);
                if (reqs.CheckRequirements(Owner.PlayerOwner) == true) {
                    Owner.PlayerOwner.IsPlacingStructure = true;
                    Owner.PlayerOwner.PlacingStructure = m_buildingType;
                    Campus.cursor.ClickMethod = delegate(Vector2 gamePoint) {
                        if (Owner.PlayerOwner.IsValidPlace) {
                            Target = gamePoint;
                            Owner.SetCurrentAbility(this);
                            Campus.cursor.ClickMethod = null;
                            Campus.cursor.ActionState = CursorActionState.idle;
                        }
                        Owner.PlayerOwner.IsPlacingStructure = false;
                    };
                } else {
                    Type unitType = BuildRequirements.Requirements.GetType(m_buildingType);
                    string name = unitType.Name;
                    Owner.PlayerOwner.CreateHUDMessage("Construction aborted for " + name + ".  You do not have sufficient resources", 10);
                }
            };
        }
        public override Ability Clone() {
            return new BuildStructureAbility(this);
        }
        public override void Update(GameTime gameTime, bool checkInput, bool updateBoundingBox) {
            if (!m_buildIsDone) {
                if (!m_ownerIsAtBuildLocation) {
                    Unit unit = (Unit)Owner;
                    MoveAbility move = (MoveAbility)unit.GetMoveAbility().Clone();
                    move.FinalDestination = (Vector2)Target;
                    move.StopDelegate = delegate() {
                        return ((Vector2)Target - Owner.Position).Length() < m_closeEnoughRange;
                    };
                    unit.FrontQueueAbility(move);
                    if (((Vector2)Target - Owner.Position).Length() < m_closeEnoughRange) {
                        m_ownerIsAtBuildLocation = true;
                        m_buildStructure = new BuildingStructure(m_buildingType, Owner.PlayerOwner, Owner.PlayerOwner.CurrentLevel, this);
                        m_buildStructure.IsUsable = false;
                        Vector2 gridPos = Cursor.GetTileAtPoint((Vector2)Target, Owner.PlayerOwner);
                        Owner.PlayerOwner.CurrentLevel.AddBaseEntityToTile(m_buildStructure, (int)gridPos.X, (int)gridPos.Y);
                        ((GarrisonAbility)m_buildStructure.Abilities["Garrison"]).Target = Owner;
                        m_buildStructure.SetCurrentAbility(m_buildStructure.Abilities["Garrison"]);
                    }
                } else {
                    m_elapsedTime += gameTime.ElapsedRealTime.Milliseconds;
                    BuildRequirements.Requirements reqs = BuildRequirements.GetRequirements(m_buildingType);
                    if (reqs.BuildTime <= m_elapsedTime) {
                        if (reqs.CheckRequirements(Owner.PlayerOwner) == true) {
                            Owner.PlayerOwner.Destroyed.Add(m_buildStructure);
                            m_buildStructure.SetCurrentAbility(m_buildStructure.Abilities["Expell Units"]);
                            m_buildIsDone = true;
                        } else {
                            Owner.PlayerOwner.Destroyed.Add(m_buildStructure);
                            m_buildStructure.SetCurrentAbility(m_buildStructure.Abilities["Expell Units"]);
                            m_buildIsDone = true;
                            Type unitType = BuildRequirements.Requirements.GetType(m_buildingType);
                            string name = unitType.Name;
                            Owner.PlayerOwner.CreateHUDMessage("Construction aborted for " + name + ".  You do not have sufficient resources", 10);
                        } 
                    }
                }
            } else {
                Structure structure = BuildRequirements.BuildStructure(m_buildingType, Owner.PlayerOwner);
                Vector2 gridPos = Cursor.GetTileAtPoint((Vector2)Target, Owner.PlayerOwner);
                BuildRequirements.Requirements reqs = BuildRequirements.GetRequirements(m_buildingType);
                Player p = Owner.PlayerOwner;
                p.AddMoney(-reqs.MoneyCost);
                p.AddResearch(-reqs.ResearchCost);
                Owner.PlayerOwner.CurrentLevel.AddBaseEntityToTile(structure, (int)gridPos.X, (int)gridPos.Y);
                if (0 < Owner.PlayerOwner.Selected.Count) {
                    if (Owner.PlayerOwner.Selected[0] is BuildingStructure) {
                        if ((BuildingStructure)Owner.PlayerOwner.CurrentUnit == m_buildStructure) {
                            Owner.PlayerOwner.CurrentUnit = structure;
                            Campus.ReloadActionMenu = true;
                        }
                    }
                }
                IsAbilityDone = true;
            }
        }
    }
}
